﻿// 247. 亚特兰蒂斯.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*
https://www.acwing.com/problem/content/249/

有几个古希腊书籍中包含了对传说中的亚特兰蒂斯岛的描述。

其中一些甚至包括岛屿部分地图。

但不幸的是，这些地图描述了亚特兰蒂斯的不同区域。

您的朋友 Bill 必须知道地图的总面积。

你自告奋勇写了一个计算这个总面积的程序。

输入格式
输入包含多组测试用例。

对于每组测试用例，第一行包含整数 n，表示总的地图数量。

接下来 n 行，描绘了每张地图，每行包含四个数字 x1,y1,x2,y2
（不一定是整数），(x1,y1)和 (x2,y2)分别是地图的左上角位置和右下角位置。

注意，坐标轴 x 轴从上向下延伸，y 轴从左向右延伸。

当输入用例 n=0 时，表示输入终止，该用例无需处理。

输出格式
每组测试用例输出两行。

第一行输出 Test case #k，其中 k 是测试用例的编号，从 1 开始。

第二行输出 Total explored area: a，其中 a 是总地图面积（即此测试用例中所有矩形的面积并，注意如果一片区域被多个地图包含，则在计算总面积时只计算一次）
，精确到小数点后两位数。

在每个测试用例后输出一个空行。

数据范围
1≤n≤10000,
0≤x1<x2≤100000,
0≤y1<y2≤100000

注意，本题 n 的范围上限加强至 10000。

输入样例：
2
10 10 20 20
15 15 25 25.5
0
输出样例：
Test case #1
Total explored area: 180.00

样例解释
样例所示地图覆盖区域如下图所示，两个矩形区域所覆盖的总面积，即为样例的解。

无标题.png
*/

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 100010;
struct ScanLine {
    double y1, y2, x;
    int mark;
    bool operator<(const ScanLine& t)const {
        return x < t.x;
    }
}line[N<<1];

struct Node {
    int l, r;
    int cnt;
    double len;
}tr[N<<2];

double b[N << 2]; //离散化数组

void pushup(int u) {
    if (tr[u].cnt)
        tr[u].len = b[tr[u].r + 1] - b[tr[u].l];
    else
        tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
}

void build(int u, int l, int r) {
    tr[u].l = l, tr[u].r = r;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
}

void modify(int u, int l, int r, int v) {
    if (l <= tr[u].l && r >= tr[u].r) {
        tr[u].cnt += v;
        pushup(u);
        return;
    }
    int mid = (tr[u].l + tr[u].r) >> 1;
    if (l <= mid) modify(u << 1, l, r, v);
    if (r > mid) modify(u << 1 | 1, l, r, v);
    //更新统计信息
    pushup(u);
}


int main()
{
    ios::sync_with_stdio(false), cin.tie(0);

    int n, T = 1;
    while (cin >> n, n) {
        //多组数据 清空
        memset(tr, 0, sizeof tr);
        memset(b, 0, sizeof b);

        for (int i = 1; i <= n; i++) {
            double x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            b[2 * i - 1] = y1;
            b[2 * i] = y2;
            line[2 * i - 1] = { y1,y2,x1,1 };
            line[2 * i] = { y1,y2,x2,-1 };
        }
        n *= 2;
        sort(line + 1, line + 1 + n);
        sort(b + 1, b + 1 + n);
        int tot = unique(b + 1, b + 1 + n) - b - 1;

        build(1, 1, tot - 1);

        double res = 0;
        for (int i = 1; i < n; i++) {
            int L = lower_bound(b + 1, b + 1 + tot, line[i].y1) - b;
            int R = lower_bound(b + 1, b + 1 + tot, line[i].y2) - b;
            modify(1, L, R - 1, line[i].mark);
            res += tr[1].len * (line[i + 1].x - line[i].x);
        }
        printf("Test case #%d\n",T++);
        printf("Total explored area: %.2lf\n\n", res);
    }

    return 0;
}

 